package org.springframework.validation.rules;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.ValidationEntity;

public class ValidationRulesContainer implements BeanFactoryAware {
	
	@Autowired
	private BeanFactory beanFactory;
	
	private Map<Class<?>, ValidationEntity> validationEntityMap = null;
	
	public ValidationEntity getValidationEntity(Class<?> clazz) {
		if (validationEntityMap == null) {
			initValidationEntityMap();
		}
		return validationEntityMap.get(clazz);
	}
	
	private void initValidationEntityMap() {
		validationEntityMap = new HashMap<Class<?>, ValidationEntity>();
		Collection<ValidationEntity> validationEntities = 
			((ListableBeanFactory) beanFactory)
			.getBeansOfType(ValidationEntity.class).values();
		for (ValidationEntity validationEntity : validationEntities) {
			validationEntityMap.put(validationEntity.getValidationClass(), validationEntity);
		}
	}

	public List<ValidationRule> getContextRules(Class<?> clazz, String state) {
		ValidationEntity entity = getValidationEntity(clazz);
		if (entity != null) {
			return getValidationEntity(clazz).getContextValidationRules(state);
		} else {
			return new ArrayList<ValidationRule>();
		}
	}
	
	public List<ValidationRule> getModelRules(Class<?> clazz) {
		ValidationEntity entity = getValidationEntity(clazz);
		if (entity != null) {
			return getValidationEntity(clazz).getModelValidationRules();
		} else {
			return new ArrayList<ValidationRule>();
		}
	}
	
	public Boolean hasModelRulesForClass(Class<?> clazz) {
		ValidationEntity entity = getValidationEntity(clazz);
		return entity != null 
			&& entity.getModelValidationRules() != null
			&& !entity.getModelValidationRules().isEmpty();
	}
	
	/**
	 * @param beanFactory the beanFactory to set
	 */
	public void setBeanFactory(BeanFactory beanFactory) {
		this.beanFactory = beanFactory;
	}

	public Boolean supportsClass(Class<?> clazz) {
		if (validationEntityMap == null) {
			initValidationEntityMap();
		}
		return validationEntityMap.containsKey(clazz);
	}
}
